from llmtcg.chat.models.openai import OpenaiCompatibleChatModel
from llmtcg.chat.model import Currency

from typing import Any, Dict, Tuple
from os import environ
from dataclasses import dataclass
from enum import Enum


@dataclass
class SiliconFlowChatModel(OpenaiCompatibleChatModel):

    """ Models that are deployed at siliconflow.cn. You need to set the environment
    variable SILICONFLOW_API_KEY or manually provide the api key when initialize
    the model instance. """

    class Model(Enum):
        SILICONFLOW_QWEN3_8B = "Qwen/Qwen3-8B"
        SILICONFLOW_DS_QWEN3_8B = "deepseek-ai/DeepSeek-R1-0528-Qwen3-8B"
        SILICONFLOW_DS_R1 = "deepseek-ai/DeepSeek-R1"
        SILICONFLOW_DS_V3 = "deepseek-ai/DeepSeek-V3"
        SILICONFLOW_DS_R1_PRO = "Pro/deepseek-ai/DeepSeek-R1"
        SILICONFLOW_DS_V3_PRO = "Pro/deepseek-ai/DeepSeek-V3"

    api_key: str = environ.get("SILICONFLOW_API_KEY", "")
    model: Model = Model.SILICONFLOW_QWEN3_8B

    @property
    def price_dict(self) -> dict:
        return {
            "Qwen/Qwen3-8B" : [0, 0],
            "deepseek-ai/DeepSeek-R1-0528-Qwen3-8B" : [0, 0],
            "deepseek-ai/DeepSeek-R1" : [4, 16],
            "deepseek-ai/DeepSeek-V3" : [2, 8],
            "Pro/deepseek-ai/DeepSeek-R1" : [4, 16],
            "Pro/deepseek-ai/DeepSeek-V3" : [2, 8],
        }

    @property
    def api_address(self) -> str:
        return "https://api.siliconflow.cn/v1/"

    @property
    def headers(self) -> Dict[str, str]:
        return {"Authorization": f"Bearer {self.api_key}"}

    @property
    def model_name(self) -> str:
        return self.model.value

    def price(self) -> Tuple[float, float, Currency]:
        if self.model_name in self.price_dict:
            price_item = self.price_dict[self.model_name]
            return price_item[0], price_item[1], Currency.CNY
        raise NotImplementedError(self.model)

    def detect_error(self, response: Any) -> Tuple[bool, str]:
        if 'code' in response:
            if response['code'] == 10003:
                return True, f"authentication error, please check API_KEY (current value is {self.api_key})"

        return False, ""

    def __hash__(self) -> int:
        return id(self)
